package com.uniflow.service;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.uniflow.entity.SystemConfig;
import com.uniflow.mapper.SystemConfigMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 系统配置服务层
 * 
 * @author uniflow
 * @since 1.0.0
 */
@Service
public class SystemConfigService {
    
    @Autowired
    private SystemConfigMapper systemConfigMapper;
    
    /**
     * 分页查询系统配置
     */
    public IPage<SystemConfig> getConfigPage(int pageNum, int pageSize, String category, String configType, Boolean isPublic, Boolean isEncrypted, String keyword) {
        Page<SystemConfig> page = new Page<>(pageNum, pageSize);
        return systemConfigMapper.selectConfigPage(page, category, configType, isPublic, isEncrypted, keyword);
    }
    
    /**
     * 根据ID查询配置
     */
    public SystemConfig getConfigById(String id) {
        return systemConfigMapper.selectById(id);
    }
    
    /**
     * 根据配置键查询
     */
    public SystemConfig getConfigByKey(String configKey) {
        return systemConfigMapper.selectByConfigKey(configKey);
    }
    
    /**
     * 获取配置值
     */
    public String getConfigValue(String configKey) {
        SystemConfig config = systemConfigMapper.selectByConfigKey(configKey);
        return config != null ? config.getConfigValue() : null;
    }
    
    /**
     * 获取配置值（带默认值）
     */
    public String getConfigValue(String configKey, String defaultValue) {
        String value = getConfigValue(configKey);
        return value != null ? value : defaultValue;
    }
    
    /**
     * 根据分类查询配置
     */
    public List<SystemConfig> getConfigsByCategory(String category) {
        return systemConfigMapper.selectByCategory(category);
    }
    
    /**
     * 查询公开配置
     */
    public List<SystemConfig> getPublicConfigs() {
        return systemConfigMapper.selectPublicConfigs();
    }
    
    /**
     * 查询私有配置
     */
    public List<SystemConfig> getPrivateConfigs() {
        return systemConfigMapper.selectPrivateConfigs();
    }
    
    /**
     * 根据配置类型查询
     */
    public List<SystemConfig> getConfigsByType(String configType) {
        return systemConfigMapper.selectByConfigType(configType);
    }
    
    /**
     * 批量查询配置
     */
    public List<SystemConfig> getConfigsByKeys(List<String> configKeys) {
        return systemConfigMapper.selectByConfigKeys(configKeys);
    }
    
    /**
     * 查询配置分类列表
     */
    public List<String> getCategories() {
        return systemConfigMapper.selectCategories();
    }
    
    /**
     * 查询配置类型列表
     */
    public List<String> getConfigTypes() {
        return systemConfigMapper.selectConfigTypes();
    }
    
    /**
     * 创建配置
     */
    @Transactional
    public SystemConfig createConfig(SystemConfig config) {
        // 生成ID
        config.setId(UUID.randomUUID().toString().replace("-", ""));
        
        // 设置创建时间
        LocalDateTime now = LocalDateTime.now();
        config.setCreatedAt(now);
        config.setUpdatedAt(now);
        
        // 检查配置键是否重复
        if (systemConfigMapper.existsByConfigKey(config.getConfigKey(), null)) {
            throw new RuntimeException("配置键已存在");
        }
        
        // 设置默认值
        if (config.getIsPublic() == null) {
            config.setIsPublic(false);
        }
        if (config.getIsEncrypted() == null) {
            config.setIsEncrypted(false);
        }
        if (config.getSortOrder() == null) {
            config.setSortOrder(0);
        }
        
        // 如果是加密配置，需要加密存储
        if (config.getIsEncrypted()) {
            config.setConfigValue(encryptValue(config.getConfigValue()));
        }
        
        systemConfigMapper.insert(config);
        return config;
    }
    
    /**
     * 更新配置
     */
    @Transactional
    public SystemConfig updateConfig(SystemConfig config) {
        // 检查配置是否存在
        SystemConfig existingConfig = systemConfigMapper.selectById(config.getId());
        if (existingConfig == null) {
            throw new RuntimeException("配置不存在");
        }
        
        // 检查配置键是否重复
        if (systemConfigMapper.existsByConfigKey(config.getConfigKey(), config.getId())) {
            throw new RuntimeException("配置键已存在");
        }
        
        // 设置更新时间
        config.setUpdatedAt(LocalDateTime.now());
        
        // 如果是加密配置，需要加密存储
        if (config.getIsEncrypted() != null && config.getIsEncrypted()) {
            config.setConfigValue(encryptValue(config.getConfigValue()));
        }
        
        systemConfigMapper.updateById(config);
        return config;
    }
    
    /**
     * 更新配置值
     */
    @Transactional
    public void updateConfigValue(String configKey, String configValue) {
        SystemConfig config = systemConfigMapper.selectByConfigKey(configKey);
        if (config == null) {
            throw new RuntimeException("配置不存在");
        }
        
        // 如果是加密配置，需要加密存储
        if (config.getIsEncrypted()) {
            configValue = encryptValue(configValue);
        }
        
        config.setConfigValue(configValue);
        config.setUpdatedAt(LocalDateTime.now());
        systemConfigMapper.updateById(config);
    }
    
    /**
     * 删除配置
     */
    @Transactional
    public void deleteConfig(String id) {
        systemConfigMapper.deleteById(id);
    }
    
    /**
     * 批量删除配置
     */
    @Transactional
    public void deleteConfigs(List<String> ids) {
        for (String id : ids) {
            systemConfigMapper.deleteById(id);
        }
    }
    
    /**
     * 查询配置统计信息
     */
    public Map<String, Object> getConfigStats() {
        return systemConfigMapper.selectConfigStats();
    }
    
    /**
     * 查询分类配置统计
     */
    public List<Map<String, Object>> getCategoryStats() {
        return systemConfigMapper.selectCategoryStats();
    }
    
    /**
     * 查询类型配置统计
     */
    public List<Map<String, Object>> getTypeStats() {
        return systemConfigMapper.selectTypeStats();
    }
    
    /**
     * 查询最近更新的配置
     */
    public List<SystemConfig> getRecentUpdated(Integer limit) {
        return systemConfigMapper.selectRecentUpdated(limit);
    }
    
    /**
     * 查询最近创建的配置
     */
    public List<SystemConfig> getRecentCreated(Integer limit) {
        return systemConfigMapper.selectRecentCreated(limit);
    }
    
    /**
     * 查询配置变更历史
     */
    public List<Map<String, Object>> getChangeHistory(String configKey, String startDate, String endDate) {
        return systemConfigMapper.selectChangeHistory(configKey, startDate, endDate);
    }
    
    /**
     * 查询未使用的配置
     */
    public List<SystemConfig> getUnusedConfigs() {
        return systemConfigMapper.selectUnusedConfigs();
    }
    
    /**
     * 重置配置到默认值
     */
    @Transactional
    public void resetToDefault(String configKey) {
        systemConfigMapper.resetToDefault(configKey);
    }
    
    /**
     * 批量重置配置
     */
    @Transactional
    public void batchResetToDefault(List<String> configKeys) {
        systemConfigMapper.batchResetToDefault(configKeys);
    }
    
    /**
     * 导出配置数据
     */
    public List<SystemConfig> exportConfigs(List<String> categories, Boolean includePrivate, Boolean includeEncrypted) {
        return systemConfigMapper.selectForExport(categories, includePrivate, includeEncrypted);
    }
    
    /**
     * 批量导入配置
     */
    @Transactional
    public void importConfigs(List<SystemConfig> configs) {
        LocalDateTime now = LocalDateTime.now();
        for (SystemConfig config : configs) {
            // 检查配置是否已存在
            SystemConfig existingConfig = systemConfigMapper.selectByConfigKey(config.getConfigKey());
            if (existingConfig != null) {
                // 更新现有配置
                config.setId(existingConfig.getId());
                config.setCreatedAt(existingConfig.getCreatedAt());
                config.setUpdatedAt(now);
                systemConfigMapper.updateById(config);
            } else {
                // 创建新配置
                config.setId(UUID.randomUUID().toString().replace("-", ""));
                config.setCreatedAt(now);
                config.setUpdatedAt(now);
                systemConfigMapper.insert(config);
            }
        }
    }
    
    /**
     * 初始化系统默认配置
     */
    @Transactional
    public void initDefaultConfigs() {
        // 检查是否已初始化
        List<SystemConfig> existingConfigs = systemConfigMapper.selectPublicConfigs();
        if (!existingConfigs.isEmpty()) {
            return;
        }
        
        // 创建默认配置
        List<SystemConfig> defaultConfigs = createDefaultConfigs();
        systemConfigMapper.insertBatch(defaultConfigs);
    }
    
    /**
     * 创建默认配置
     */
    private List<SystemConfig> createDefaultConfigs() {
        LocalDateTime now = LocalDateTime.now();
        
        return Arrays.asList(
            // 系统基础配置
            createConfig("system.name", "统一工作流平台", "string", "系统配置", "系统名称", true, false, 1, now),
            createConfig("system.version", "1.0.0", "string", "系统配置", "系统版本", true, false, 2, now),
            createConfig("system.description", "企业级统一工作流平台", "string", "系统配置", "系统描述", true, false, 3, now),
            
            // 安全配置
            createConfig("security.jwt.secret", "uniflow-jwt-secret-key", "encrypted", "安全配置", "JWT密钥", false, true, 1, now),
            createConfig("security.jwt.expiration", "86400", "number", "安全配置", "JWT过期时间（秒）", false, false, 2, now),
            createConfig("security.password.min.length", "8", "number", "安全配置", "密码最小长度", false, false, 3, now),
            createConfig("security.login.max.attempts", "5", "number", "安全配置", "最大登录尝试次数", false, false, 4, now),
            
            // 邮件配置
            createConfig("mail.smtp.host", "smtp.example.com", "string", "邮件配置", "SMTP服务器", false, false, 1, now),
            createConfig("mail.smtp.port", "587", "number", "邮件配置", "SMTP端口", false, false, 2, now),
            createConfig("mail.smtp.username", "noreply@example.com", "string", "邮件配置", "SMTP用户名", false, false, 3, now),
            createConfig("mail.smtp.password", "password", "encrypted", "邮件配置", "SMTP密码", false, true, 4, now),
            
            // 文件存储配置
            createConfig("file.storage.type", "local", "string", "文件配置", "存储类型", false, false, 1, now),
            createConfig("file.storage.path", "/data/uploads", "string", "文件配置", "存储路径", false, false, 2, now),
            createConfig("file.max.size", "10485760", "number", "文件配置", "最大文件大小（字节）", false, false, 3, now),
            
            // 工作流配置
            createConfig("workflow.auto.deploy", "true", "boolean", "工作流配置", "自动部署", false, false, 1, now),
            createConfig("workflow.history.cleanup.days", "90", "number", "工作流配置", "历史数据清理天数", false, false, 2, now),
            
            // API配置
            createConfig("api.rate.limit.enabled", "true", "boolean", "API配置", "启用限流", false, false, 1, now),
            createConfig("api.rate.limit.requests", "1000", "number", "API配置", "每分钟请求数限制", false, false, 2, now)
        );
    }
    
    /**
     * 创建配置对象
     */
    private SystemConfig createConfig(String key, String value, String type, String category, String description, boolean isPublic, boolean isEncrypted, int sortOrder, LocalDateTime now) {
        SystemConfig config = new SystemConfig();
        config.setId(UUID.randomUUID().toString().replace("-", ""));
        config.setConfigKey(key);
        config.setConfigValue(isEncrypted ? encryptValue(value) : value);
        config.setConfigType(type);
        config.setCategory(category);
        config.setDescription(description);
        config.setIsPublic(isPublic);
        config.setIsEncrypted(isEncrypted);
        config.setSortOrder(sortOrder);
        config.setCreatedAt(now);
        config.setUpdatedAt(now);
        return config;
    }
    
    /**
     * 加密配置值
     */
    private String encryptValue(String value) {
        // 这里应该使用真实的加密算法
        // 为了简化，这里只是简单的Base64编码
        try {
            return java.util.Base64.getEncoder().encodeToString(value.getBytes("UTF-8"));
        } catch (Exception e) {
            throw new RuntimeException("配置值加密失败", e);
        }
    }
    
    /**
     * 解密配置值
     */
    private String decryptValue(String encryptedValue) {
        // 这里应该使用真实的解密算法
        // 为了简化，这里只是简单的Base64解码
        try {
            return new String(java.util.Base64.getDecoder().decode(encryptedValue), "UTF-8");
        } catch (Exception e) {
            throw new RuntimeException("配置值解密失败", e);
        }
    }
    
    /**
     * 获取解密后的配置值
     */
    public String getDecryptedConfigValue(String configKey) {
        SystemConfig config = systemConfigMapper.selectByConfigKey(configKey);
        if (config == null) {
            return null;
        }
        
        if (config.getIsEncrypted()) {
            return decryptValue(config.getConfigValue());
        } else {
            return config.getConfigValue();
        }
    }
}